package mws;

import java.util.concurrent.*;

/**
 * 阻塞队列工厂类，使用枚举类型指定队列类型，提供类型安全的创建方式
 */
public class BlockingQueueFactory {

    /**
     * 支持的阻塞队列类型枚举
     */
    public enum QueueType {
        ARRAY_BLOCKING_QUEUE,
        LINKED_BLOCKING_QUEUE,
        PRIORITY_BLOCKING_QUEUE,
        SYNCHRONOUS_QUEUE
    }

    /**
     * 创建基于数组的有界阻塞队列
     * @param capacity 队列容量
     * @param fair 是否使用公平锁策略
     * @param <E> 队列元素类型
     * @return 数组阻塞队列实例
     */
    public static <E> BlockingQueue<E> createArrayBlockingQueue(int capacity, boolean fair) {
        return new ArrayBlockingQueue<>(capacity, fair);
    }

    /**
     * 创建基于链表的阻塞队列（无界）
     * @param <E> 队列元素类型
     * @return 链表阻塞队列实例
     */
    public static <E> BlockingQueue<E> createLinkedBlockingQueue() {
        return new LinkedBlockingQueue<>();
    }

    /**
     * 创建基于链表的有界阻塞队列
     * @param capacity 队列容量
     * @param <E> 队列元素类型
     * @return 链表阻塞队列实例
     */
    public static <E> BlockingQueue<E> createLinkedBlockingQueue(int capacity) {
        if(capacity <= 0)
            return new LinkedBlockingQueue<>();
        return new LinkedBlockingQueue<>(capacity);
    }

    /**
     * 创建优先级阻塞队列
     * @param initialCapacity 初始容量
     * @param <E> 队列元素类型（需实现Comparable）
     * @return 优先级阻塞队列实例
     */
    public static <E extends Comparable<? super E>> BlockingQueue<E> createPriorityBlockingQueue(int initialCapacity) {
        return new PriorityBlockingQueue<>(initialCapacity);
    }

    /**
     * 创建同步队列
     * @param fair 是否使用公平模式
     * @param <E> 队列元素类型
     * @return 同步队列实例
     */
    public static <E> BlockingQueue<E> createSynchronousQueue(boolean fair) {
        return new SynchronousQueue<>(fair);
    }

    /**
     * 根据枚举类型创建队列实例（通用创建方法）
     * @param queueType 队列类型（枚举）
     * @param capacity 容量参数（对不同队列有不同含义）
     * @param fair 是否公平
     * @param <E> 队列元素类型
     * @return 阻塞队列实例
     */
    public static <E> BlockingQueue<E> createQueue(QueueType queueType, int capacity, boolean fair) {
        switch (queueType) {
            case ARRAY_BLOCKING_QUEUE:
                return createArrayBlockingQueue(capacity, fair);
            case LINKED_BLOCKING_QUEUE:
                return capacity > 0 ? createLinkedBlockingQueue(capacity) : createLinkedBlockingQueue();
            case PRIORITY_BLOCKING_QUEUE:
                // 优先级队列的capacity作为初始容量
                return (BlockingQueue<E>) createPriorityBlockingQueue(Math.max(capacity, 11));
            case SYNCHRONOUS_QUEUE:
                return createSynchronousQueue(fair);
            default:
                throw new IllegalArgumentException("不支持的队列类型: " + queueType);
        }
    }
}
